﻿using VIT.Library;
using VIT.Library.Web;
using VIT.Web.Controls;

using System.Collections.Generic;
using System;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Data;
using System.Web;
using System.Xml;
using System.Threading;
using System.Web.SessionState;

namespace VIT.Web.UI
{
    abstract public class VITComponent : AbsVITPage
    {
        protected VIT.DataHelper.DataAccess.SQLSupport sqlSupport = new VIT.DataHelper.DataAccess.SQLSupport();

        protected override void InitializeCulture()
        {
            string culture = Session["language"].ToString();
            if (!string.IsNullOrEmpty(culture))
            {
                UICulture = culture;
                Culture = culture;
            }
        }

        protected void Page_PreInit(Object sender, System.EventArgs e)
        {
            VITComponent p = (VITComponent)sender;
            if (p.URLCurrentPath.ToLower().Contains("admin"))
            {
                // kiểm tra bản quền
                bool bug;
                StringBuilder strQuery = new StringBuilder();
                strQuery.Append("select Keys from WebConfig where LanguageId='");
                strQuery.Append(HttpContext.Current.Session["language"]);
                strQuery.Append("'");
                object keys = sqlSupport.ExecuteScalar(false, strQuery.ToString());
                if (keys != null)
                {
                    string confirm = Encrypt.EnCode(URL.baseUrl).EnCodeMD5();
                    var lstKeys = keys.ToString().Split('|');
                    if (lstKeys.Contains(confirm)) bug = true;
                    else bug = false;
                }
                else bug = false;
                if (!bug) HttpContext.Current.Response.Redirect(URL.baseUrl + "admin/Restrict.aspx?msg=" + Server.UrlEncode("Tên miền chưa được đăng ký"));

                // kiểm tra quyền
                string function = System.IO.Path.GetFileName(Request.Path);
                MainCore.CheckPermission(function.ToString());
            }

            string TemplateName = loadTemplate(this);

            loadModule(this.Master);
            loadModule(this, TemplateName);
        }

        #region inherit interface
        public override string linkComponent(string ComponentName, string View = "", string Param = "")
        {
            return URL.linkComponent(ComponentName, View, Param);
        }
        public override void RedirectComponent(string ComponentName, string View = "", string Param = "")
        {
            Response.Redirect(URL.linkComponent(ComponentName, View, Param));
        }
        public override void TransferComponent(string ComponentName, string View = "", string Param = "")
        {
            Server.Transfer(URL.linkComponent(ComponentName, View, Param));
        }
        #endregion

        private bool isAdminPath = false;
        #region load Template & Module
        private string TemplatePath
        {
            get
            {
                string curentPath = URL.getCurrentPath();
                isAdminPath = curentPath.ToLower().Contains("admin");
                if (isAdminPath) return Convert.ToString(HttpContext.Current.Application["TemplatePathAdmin"]);
                return Convert.ToString(HttpContext.Current.Application["TemplatePath"]);
            }
            set
            {
                string curentPath = URL.getCurrentPath();
                bool isAdminPath = curentPath.ToLower().Contains("admin");
                if (isAdminPath) HttpContext.Current.Application["TemplatePathAdmin"] = value;
                else HttpContext.Current.Application["TemplatePath"] = value;
            }
        }
        private string TemplateName
        {
            get
            {
                string curentPath = URL.getCurrentPath();
                bool isAdminPath = curentPath.ToLower().Contains("admin");
                if (isAdminPath) return Convert.ToString(HttpContext.Current.Application["TemplateNameAdmin"]);
                return Convert.ToString(HttpContext.Current.Application["TemplateName"]);
            }
            set
            {
                string curentPath = URL.getCurrentPath();
                bool isAdminPath = curentPath.ToLower().Contains("admin");
                if (isAdminPath) HttpContext.Current.Application["TemplateNameAdmin"] = value;
                else HttpContext.Current.Application["TemplateName"] = value;
            }
        }

        private string loadTemplate(VITComponent Page)
        {
            string TemplatePath = string.Empty;
            string TemplateName = Page.Request.Params.Get("tpl");
            string curentPath = URL.getCurrentPath();
            bool isAdminPath = curentPath.ToLower().Contains("admin");
            if (string.IsNullOrEmpty(TemplateName))
            {
                TemplateName = this.TemplateName;
                TemplatePath = this.TemplatePath;
                if (string.IsNullOrEmpty(TemplateName) || string.IsNullOrEmpty(TemplatePath))
                {
                    if (isAdminPath) TemplateName = "AdminTemplate";
                    else TemplateName = "PreTemplate";

                    StringBuilder strQuery = new StringBuilder();
                    strQuery.Append("select AdminTemplate, PreTemplate, TemplateConfigBy from WebConfig where LanguageId='");
                    strQuery.Append(HttpContext.Current.Session["language"]);
                    strQuery.Append("'");
                    DataTable table = sqlSupport.ExecuteDataset(false, strQuery.ToString()).Tables[0];
                    TemplateName = table.Rows[0]["PreTemplate"].ToString();
                    if (sqlSupport.ExecuteDataset(false, strQuery.ToString()).Tables[0].Rows.Count > 0)
                    {
                        if (curentPath.ToLower().Contains("admin")) TemplateName = table.Rows[0]["AdminTemplate"].ToString();
                        else
                        {
                            string TemplateConfig = table.Rows[0]["TemplateConfigBy"].ToString();
                            if (TemplateConfig.Length > 0)
                            {
                                // load template tu bang TemplateConfig
                                int date = MainCore.GetDayByTemplateConfig(TemplateConfig);
                                StringBuilder template = new StringBuilder();
                                template.Append("select TemplateName from TemplateConfig where FromDate <= ");
                                template.Append(date);
                                template.Append(" and ");
                                template.Append(date);
                                template.Append(" <= ToDate and LanguageId='");
                                template.Append(HttpContext.Current.Session["language"]);
                                template.Append("'");
                                object tempcon = sqlSupport.ExecuteScalar(false, template.ToString());
                                if (tempcon != null) TemplateName = tempcon.ToString();
                            }
                        }
                    }

                    // ------
                    StringBuilder str = new StringBuilder();
                    str.Append(URL.appPath);
                    if (isAdminPath) str.Append("admin/");
                    str.Append("templates/");
                    str.Append(TemplateName);
                    str.Append("/");

                    TemplatePath = str.ToString();
                    this.TemplatePath = TemplatePath;
                    this.TemplateName = TemplateName;
                    //Page.Application["TemplatePath"] = TemplatePath;
                    //Page.Application["TemplateName"] = TemplateName;
                }
            }
            else
            {
                StringBuilder str = new StringBuilder();
                str.Append(URL.appPath);
                if (isAdminPath) str.Append("admin/");
                str.Append("templates/");
                str.Append(TemplateName);
                str.Append("/");

                TemplatePath = str.ToString();
            }
            Page.MasterPageFile = TemplatePath + TemplateName + ".master";
            this.URLTemplatePath = TemplatePath;
            return TemplateName;
        }

        private ModuleData GetModuleData(HttpApplicationState app, HttpSessionState session, string pathPositionFile, int type, string TemplateName = "")
        {
            if (app == null || session == null) return null;
            string moduleDataStr = "ModuleData";// +type.ToString();
            var result = app[moduleDataStr] as Dictionary<string, ModuleData>;
            if (result == null)
            {
                result = new Dictionary<string, ModuleData>();
                app[moduleDataStr] = result;
            }
            string key = pathPositionFile + (type == 1 ? URL.getCurrentView() : string.Empty);
            if (!result.ContainsKey(key))
            {
                var md = new ModuleData();
                var listpositions = MainCore.getPositions(pathPositionFile);
                md.Positions = listpositions.Keys.ToArray();
                result.Add(pathPositionFile, md);
                if (type == 0) // For MasterPage
                {
                    foreach (var position in md.Positions)
                    {
                        StringBuilder sqlCommand = new StringBuilder();
                        sqlCommand.Append("select Name, Title, Param, TemplatePosition from Module m, Module_Language la where Id=ModuleId and LanguageID='");
                        sqlCommand.Append(session["language"]);
                        sqlCommand.Append("' and Deleted=0 and Published=1 and TemplatePosition='");
                        sqlCommand.Append(position);
                        sqlCommand.Append("' order by TemplatePosition , Orders");
                        DataTable dt = sqlSupport.ExecuteDataset(false, sqlCommand.ToString()).Tables[0];
                        if (dt != null)
                        {
                            var lstPathModules = new List<string>();
                            var lstListParams = new List<string>();
                            var lstTitles = new List<string>();
                            foreach (DataRow row in dt.Rows)
                            {
                                StringBuilder pathModule = new StringBuilder();
                                pathModule.Append(URL.appPath);
                                if (isAdminPath) pathModule.Append("admin/Modules/");
                                else pathModule.Append("Modules/");
                                pathModule.Append(row["Name"]);
                                pathModule.Append("/");
                                pathModule.Append(row["Name"]);
                                pathModule.Append(".ascx");
                                lstPathModules.Add(pathModule.ToString());
                                lstListParams.Add(Convert.ToString(row["Param"]));
                                lstTitles.Add(Convert.ToString(row["Title"]));
                            }
                            md.PathModules[position] = lstPathModules.ToArray();
                            md.ListParams[position] = lstListParams.ToArray();
                            md.Titles[position] = lstTitles.ToArray();
                        }
                    }
                }
                else if (type == 1) // For Component
                {
                    string[] folder = URL.getCurrentPath().Split('/');
                    string viewName = URL.getCurrentView();

                    string ComponentName = folder[folder.Length - 1];

                    foreach (var position in md.Positions)
                    {
                        StringBuilder sqlCommand = new StringBuilder();
                        sqlCommand.Append("select Name, Title, Param, ComponentPosition from Module m, Module_Language la where Id=ModuleId and LanguageID='");
                        sqlCommand.Append(session["language"]);
                        sqlCommand.Append("' and ComponentName='");
                        sqlCommand.Append(ComponentName);
                        sqlCommand.Append("' and ViewName='");
                        sqlCommand.Append(viewName);
                        sqlCommand.Append("' and (TemplateName='");
                        sqlCommand.Append(TemplateName);
                        sqlCommand.Append("' ");
                        //sqlCommand.Append(" or TemplateName='' or TemplateName is null");
                        sqlCommand.Append(") and Deleted=0 and Published=1 and ComponentPosition='");
                        sqlCommand.Append(position);
                        sqlCommand.Append("' order by ComponentPosition , Orders");
                        DataTable dt = sqlSupport.ExecuteDataset(false, sqlCommand.ToString()).Tables[0];
                        if (dt != null)
                        {
                            var lstPathModules = new List<string>();
                            var lstListParams = new List<string>();
                            var lstTitles = new List<string>();
                            foreach (DataRow row in dt.Rows)
                            {
                                StringBuilder pathModule = new StringBuilder();
                                pathModule.Append(URL.appPath);
                                if (isAdminPath) pathModule.Append("Admin/Modules/");
                                else pathModule.Append("Modules/");
                                pathModule.Append(row["Name"]);
                                pathModule.Append("/");
                                pathModule.Append(row["Name"]);
                                pathModule.Append(".ascx");
                                lstPathModules.Add(pathModule.ToString());
                                lstListParams.Add(Convert.ToString(row["Param"]));
                                lstTitles.Add(Convert.ToString(row["Title"]));
                            }
                            md.PathModules[position] = lstPathModules.ToArray();
                            md.ListParams[position] = lstListParams.ToArray();
                            md.Titles[position] = lstTitles.ToArray();
                        }
                    }
                }
            }

            return result[pathPositionFile];
        }

        private void loadModule(System.Web.UI.MasterPage page)
        {
            VITModule control;
            Skin skin;
            //if(HttpContext.Current.Application["Skin"]
            StringBuilder str = new StringBuilder();
            //str.Append(page.Application["TemplatePath"]);
            str.Append(this.TemplatePath);
            str.Append("Position.xml");
            var md = GetModuleData(page.Application, page.Session, page.Server.MapPath(str.ToString()), 0);

            foreach (var position in md.Positions)
            {
                skin = (Skin)page.FindControl(position);
                if (skin != null)
                {
                    StringBuilder pathSkin = new StringBuilder();
                    pathSkin.Append(URL.appPath);
                    if (isAdminPath) pathSkin.Append("admin/Skins/");
                    else pathSkin.Append("Skins/");
                    pathSkin.Append(skin.SkinName);
                    pathSkin.Append(".ascx");
                    var count = md.PathModules[position].Length;
                    var pathModules = md.PathModules[position];
                    var listParams = md.ListParams[position];
                    var listTitles = md.Titles[position];
                    for (int i = 0; i < count; i++)
                    {
                        control = page.LoadControl(pathModules[i]) as VITModule;
                        if (listParams[i].Length > 0)
                        {
                            control.Params = new Dictionary<string, string>();
                            string[] listParam = listParams[i].Split('|');
                            if (listParam.Length > 0)
                            {
                                foreach (var item in listParam)
                                {
                                    string[] p = item.Split('=');
                                    control.Params.Add(p[0], p[1]);
                                }
                            }
                        }
                        VITSkin controlSkin = page.LoadControl(pathSkin.ToString()) as VITSkin;
                        System.Web.UI.Control c = controlSkin.FindControl("PlaceHolderContent");
                        if (c != null) c.Controls.Add(control);
                        controlSkin.Title = listTitles[i];

                        skin.Controls.Add(controlSkin);
                    }
                }
            }
        }
        private void loadModule(VITComponent page, string TemplateName)
        {
            VITModule control;
            Skin skin;
            StringBuilder str = new StringBuilder();

            str.Append(URL.getCurrentPath());
            str.Append("/Position.xml");
            var md = GetModuleData(page.Application, page.Session, page.Server.MapPath(str.ToString()), 1, TemplateName);

            foreach (var position in md.Positions)
            {
                //skin = (Skin)page.FindControl(position);
                skin = page.Master.FindControl("MainContent").FindControl(position) as Skin;
                if (skin != null)
                {
                    StringBuilder pathSkin = new StringBuilder();
                    pathSkin.Append(URL.appPath);
                    if (isAdminPath) pathSkin.Append("admin/Skins/");
                    else pathSkin.Append("Skins/");
                    pathSkin.Append(skin.SkinName);
                    pathSkin.Append(".ascx");
                    var count = md.PathModules[position].Length;
                    var pathModules = md.PathModules[position];
                    var listParams = md.ListParams[position];
                    var listTitles = md.Titles[position];
                    for (int i = 0; i < count; i++)
                    {
                        control = page.LoadControl(pathModules[i]) as VITModule;
                        if (listParams[i].Length > 0)
                        {
                            control.Params = new Dictionary<string, string>();
                            string[] listParam = listParams[i].Split('|');
                            if (listParam.Length > 0)
                            {
                                foreach (var item in listParam)
                                {
                                    string[] p = item.Split('=');
                                    control.Params.Add(p[0], p[1]);
                                }
                            }
                        }
                        VITSkin controlSkin = (VITSkin)page.LoadControl(pathSkin.ToString());
                        System.Web.UI.Control c = controlSkin.FindControl("PlaceHolderContent");
                        if (c != null) c.Controls.Add(control);
                        controlSkin.Title = listTitles[i];

                        skin.Controls.Add(controlSkin);
                    }
                }
            }
        }
        #endregion

        private class ModuleData
        {
            public ModuleData()
            {
                PathModules = new Dictionary<string, string[]>();
                ListParams = new Dictionary<string, string[]>();
                Titles = new Dictionary<string, string[]>();
            }

            public string[] Positions { get; set; }
            public Dictionary<string, string[]> PathModules { get; private set; }
            public Dictionary<string, string[]> ListParams { get; private set; }
            public Dictionary<string, string[]> Titles { get; private set; }
        }
    }
}
